package kMesh;

public class IndexTable {
	private IndexList[] lists;

	public IndexTable() {
		lists = new IndexList[0];
	}

	public IndexTable(int[][] initalData) {
		lists = new IndexList[initalData.length];
		for (int n = 0; n < initalData.length; n++) {
			lists[n] = new IndexList(initalData[n]);
		}
	}

	/*
	 * GETS AND SETS
	 * 
	 * 
	 * 
	 */

	public int[] getAt(int tableIndex) {
		return lists[tableIndex].toArray();
	}

	public int getAt(int tableIndex, int cellIndex) {
		return lists[tableIndex].getAt(cellIndex);
	}

	public boolean setAt(int tableIndex, int[] cellValue) {
		lists[tableIndex] = new IndexList(cellValue);
		return true;
	}

	public boolean setAt(int tableIndex, int cellIndex, int value) {
		return lists[tableIndex].setAt(cellIndex, value);
	}

	public int count() {
		return lists.length;
	}
	
	public int count( int tableIndex ) {
		return lists[tableIndex].count();
	}

	/*
	 * CELL MANIPULATION
	 * 
	 * 
	 * 
	 */

	/**
	 * adds a given integer to a given cell
	 * 
	 * @param cellIndex
	 * @param value
	 */
	public boolean appendToCell(int cellIndex, int value) {
		return lists[cellIndex].append(value);
	}

	/**
	 * adds a bunch of given integers to a given cell
	 * 
	 * @param cellIndex
	 * @param values
	 */
	public boolean appendToCell(int cellIndex, int[] values) {
		return lists[cellIndex].append(values);
	}

	/**
	 * removes an integer from a given position in a given cell and returns its value
	 * 
	 * @param cellIndex
	 * @param indexOfValueToRemove
	 */
	//TODO: rename to POP
	public int removeFromCellAt(int cellIndex, int indexOfValueToRemove) {
		return lists[cellIndex].popAt(indexOfValueToRemove);
	}

	/**
	 * looks for a value in a given cell. if found, returns its index,
	 * otherwise returns -1
	 * 
	 * @param cellIndex
	 * @param valueToLookFor
	 */
	public int indexOfValueInCell(int cellIndex, int valueToLookFor) {
		return lists[cellIndex].indexOfValue(valueToLookFor);
	}

	/**
	 * removes a given value from a cell if it exists, and returns true if
	 * not, returns false
	 * 
	 * @param cellIndex
	 * @param indexOfValueToRemove
	 */
	public boolean removeValueFromCellIfFound(int cellIndex, int valueToRemove) {
		int x = lists[cellIndex].indexOfValue(valueToRemove);
		if (x>=0) {
			lists[cellIndex].removeAt(x);
			return true;
		} else {
			return false;
		}
	}

	/**
	 * scans cell, and subtracts one from any values which are grater than a
	 * given horizon value
	 * 
	 * @param cellIndex
	 * @param horizonValue
	 */
	public void reindexCellDown(int cellIndex, int horizonValue) {
		lists[cellIndex].reindexDown(horizonValue);
	}

	/*
	 * TABLE MANIPULATION
	 * 
	 * 
	 * 
	 */
	
	/**
	 * adds new cells to the table
	 * 
	 * @param cellValues
	 */
	public void append(int[] cellValues) {
		append(new IndexList(cellValues));
	}
	
	/**
	 * adds new cells to the table
	 * 
	 * @param cellValues
	 */
	public void append(IndexList cellValues) {
		IndexList[] ret = new IndexList[lists.length + 1];
		for (int n = 0; n < lists.length; n++) {
			ret[n] = lists[n];
		}
		ret[lists.length] = cellValues;
		lists = ret;
	}

	/**
	 * removes a cell from the table
	 * 
	 * @param tableIndexToRemove
	 */
	public void remove(int tableIndexToRemove) {
		IndexList[] ret = new IndexList[lists.length - 1];
		int x = 0;
		for (int i = 0; i < lists.length; i++) {
			if (i != tableIndexToRemove) {
				ret[x] = lists[i];
				x++;
			}
		}
		lists = ret;
	}

	/**
	 * scans table, and subtracts one from any values which are grater than
	 * a given horizon value
	 * 
	 * @param cellIndex
	 * @param horizonValue
	 */
	public void reindexDown(int horizonValue) {
		for (int i = 0; i < lists.length; i++) {
			reindexCellDown(i, horizonValue);
		}
	}
	
	public String toString(int i){
		return lists[i].toString();
	}
	
	public String toString(){
		String str = "";
		for (int i = 0; i < lists.length; i++) {
			str+= "("+i+")"+toString(i);
		}
		return str;
	}

}